package com.horizon.common.configuration;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * Druid数据源配置类
 *
 * @author wangfuwei
 * @version 2018-08-02
 */
@ConditionalOnClass({StatViewServlet.class, WebStatFilter.class})
@SpringBootConfiguration
public class DruidConfiguration {

    @Autowired
    private Environment environment;

    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    /**
     * 配置管理后台servlet
     */
    @Bean
    public ServletRegistrationBean<StatViewServlet> statViewServlet() {
        ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>(new StatViewServlet(), druidProperties().getUrlMappings());
        Map<String, String> initParameters = new HashMap<>();
        //后台管理用户
        initParameters.put(StatViewServlet.PARAM_NAME_USERNAME, druidProperties().getLoginUsername());
        initParameters.put(StatViewServlet.PARAM_NAME_PASSWORD, druidProperties().getLoginPassword());
        //白名单
        initParameters.put(StatViewServlet.PARAM_NAME_ALLOW, druidProperties().getAllow());
        //黑名单，优先级高于白名单
        initParameters.put(StatViewServlet.PARAM_NAME_DENY, druidProperties().getDeny());
        //是否可重置数据
        initParameters.put(StatViewServlet.PARAM_NAME_RESET_ENABLE, druidProperties().getResetEnable());
        servletRegistrationBean.setInitParameters(initParameters);
        return servletRegistrationBean;
    }

    /**
     * 配置监控Filter
     */
    @Bean
    public FilterRegistrationBean<WebStatFilter> webStatFilter() {
        FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<>(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");//过滤规则

        StringBuilder exclusions = new StringBuilder();
        String staticPath = environment.getProperty("spring.mvc.static-path-pattern");
        if (!StringUtils.isEmpty(staticPath) && !staticPath.equals("/**")) {
            exclusions.append(staticPath.replace("**", "*"));
        }
        if (druidProperties().getUrlMappings().length > 0) {
            for (String urlMapping : druidProperties().getUrlMappings()) {
                if (!StringUtils.isEmpty(exclusions.toString())) exclusions.append(",");
                exclusions.append(urlMapping);
            }
        }

        filterRegistrationBean.addInitParameter("exclusions", exclusions.toString());//不需要过滤的规则
        return filterRegistrationBean;
    }

    /**
     * Druid后台管理配置参数
     */
    @Bean
    public DruidProperties druidProperties() {
        return new DruidProperties();
    }

    @Getter
    @Setter
    @ConfigurationProperties("spring.datasource.druid")
    class DruidProperties {
        private String[] urlMappings = {"/druid/*"};
        private String loginUsername = "";
        private String loginPassword = "";
        private String allow = "";
        private String deny = "";
        private String resetEnable = "true";
    }
}
